package com.iqik.base.zk.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CreateBuilder;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

public class CuratorDemo {

    public static void createSession() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.newClient("132.232.16.135:2181", retryPolicy);
        client.start();
        System.out.println("不使用fluent变成风格");
    }

    public static CuratorFramework createSessionWithFluent() {
        // 重新连接策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("132.232.16.135:2181")
                .sessionTimeoutMs(50000)
                .connectionTimeoutMs(30000)
                .retryPolicy(retryPolicy)
                .namespace("base") // 独立的命名空间 在/base目录下
                .build();
        client.start();
        System.out.println("使用fluent变成风格");
        return client;
    }

    public static void createNode() {
        CuratorFramework client = createSessionWithFluent();
        CreateBuilder createBuilder = client.create();
        String curator_fluent_node = "";
        try {
//            curator_fluent_node = createBuilder.forPath("/curator_fluent_node2", "curator client fluent 内容".getBytes());
//            System.out.println("创建节点 " + curator_fluent_node);
            client.delete().forPath("/curator_fluent_node2");
            System.out.println("删除节点 " + curator_fluent_node);
            // 递归创建node
            String forPath = createBuilder.creatingParentContainersIfNeeded()
                    .withMode(CreateMode.PERSISTENT_SEQUENTIAL)
                    .forPath("/curator_fluent_node/sequential", "递归创建节点".getBytes());
            // sequential0000000000
            System.out.println("递归创建node" + forPath);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void getNodeContext() {
        CuratorFramework client = createSessionWithFluent();
        try {
            // 获取序列节点不能通过原有的节点名而是通过节点名+序列号获取数据
            byte[] bytes = client.getData().forPath("/curator_fluent_node/sequential0000000001");
            System.out.println(new String(bytes));
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 状态信息
        Stat stat = new Stat();
        try {
            client.getData().storingStatIn(stat).forPath("/curator_fluent_node/sequential0000000001");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(stat);
    }

    public static void setNodeContext() {
        CuratorFramework client = createSessionWithFluent();
        String path = "/curator_fluent_node/sequential0000000001";
        Stat stat = new Stat();
        try {
            // 获取序列节点不能通过原有的节点名而是通过节点名+序列号获取数据
            byte[] bytes = client.getData().forPath(path);
            client.getData().storingStatIn(stat).forPath(path);
            System.out.println(new String(bytes));
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            int version = client.setData().withVersion(stat.getVersion()).forPath(path, "更新数据".getBytes()).getVersion();
            System.out.println("now version: " + version);
            System.out.println("当前节点修改之后的内容： " + new String(client.getData().forPath(path)));
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            int version = client.setData().withVersion(stat.getVersion()).forPath(path, "更新数据".getBytes()).getVersion();
            System.out.println("now version: " + version);
            System.out.println("当前节点修改之后的内容： " + new String(client.getData().forPath(path)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
//        createSession();
//        createSessionWithFluent();
//        createNode();
//        getNodeContext();
        setNodeContext();
    }

}
